package com.sencorsta.ids.talk.OpenHandler;

 import com.alibaba.fastjson.JSONObject;
import com.google.protobuf.InvalidProtocolBufferException;
import com.sencorsta.ids.common.information.ErrorCodeList;
import com.sencorsta.ids.common.proto.utils.ReturnUtils;
import com.sencorsta.ids.common.service.*;
import com.sencorsta.ids.core.entity.ClientEvent;
import com.sencorsta.ids.core.log.Out;
import com.sencorsta.ids.core.tcp.opensocket.OpenMessageHandler;
import com.sencorsta.ids.core.tcp.socket.protocol.RpcMessage;
import com.sencorsta.ids.talk.proto.ImtalkOutGroupByProto;
import com.sencorsta.ids.talk.proto.ImtalkPushGroupUpdateMsg;
import com.sencorsta.ids.talk.proto.ImtalkPushMessageByProto;
import com.sencorsta.utils.date.DateUtil;
import io.netty.channel.Channel;

import java.util.List;

/**
* @description: 退出群聊
* @author TAO
* @date 2019/7/23 14:29
*/
//TODO 可以优化case代码
@ClientEvent("OutGroup")
public class OutGroupHandler extends OpenMessageHandler implements RedisService {

    @Override
    public RpcMessage request(Channel channel, JSONObject json, String content, byte[] data, byte[] protobuf) {
        Out.debug("-------------------------退出群聊----------------------------");
        ImtalkOutGroupByProto.OutGroupRes.Builder res=ImtalkOutGroupByProto.OutGroupRes.newBuilder();

        //服务器推的群状态跟新
        ImtalkPushGroupUpdateMsg.PushGroupUpdate.Builder pushUpdate= ImtalkPushGroupUpdateMsg.PushGroupUpdate.newBuilder();

        //服务器推送的消息
        //创建传输到服务器的protobuf
        ImtalkPushMessageByProto.PushMsg.Builder pushsys= ImtalkPushMessageByProto.PushMsg.newBuilder();

        try{

            ImtalkOutGroupByProto.OutGroupReq req=ImtalkOutGroupByProto.OutGroupReq.parseFrom(protobuf);
            res.setSign(req.getSign());
            //得到退出类型
            int type=req.getType();//1.单退  2.群退  3.解散

            //得到群Id
            String groupId=req.getGroupId();
            //判断该群是否存在
            if (!R_GROUP.exists(groupId)){
                return error(ErrorCodeList.GROUP_IS_NULL);
            }

            //得到要退的目标  可能是一个，可能是多个
            List<String> tagIdList=req.getTagIdList();
            Out.debug("退出的人"+tagIdList);

           //获取当前群的人数
            int count= Integer.parseInt(R_PROPERTY.hget(groupId,"count"));

            //得到当前用户的权限
            JSONObject member= JSONObject.parseObject((R_GROUP.hget(groupId,userId)));
            String adminType= String.valueOf(member.get("adminType"));//权限级别

            //获取群成员id列表
            Object[] memberList = R_GROUP.hkeys(groupId).toArray();

            //定义系统消息
            JSONObject msg=new JSONObject();
            switch (type){
                case 1://单退
                    Out.debug("----------------------单退---------------------------");
                    //for (int i=0;i<tagIdList.size();i++){
                        //在群里删除该用户

                        R_GROUP.hdel(groupId,userId );

                        //在用户-群的关系中判断这个用户中是否有该群

                        if (R_USER_R_GROUP.exists(String.valueOf(tagIdList.get(0)))){
                            Out.warn("-----------------当前用户保存了该群--需要解除------------------");
                            R_USER_R_GROUP.lrem(userId,0,groupId);
                           /* Long jsz=R_USER_R_GROUP.lrem(userId,0,groupId);
                            Out.debug(jsz);
                            //将群-用户关系解除
                            if (jsz<1){
                                Out.error("---------群-用户关系解除失败！！！-----------");
                                return error(ErrorCodeList.GROUP_USER__ERROR);
                            }*/
                        }
                    //}

                    msg.put("msgContent",R_USER.hget(userId,NICKNAME)+"退出群聊");
                    //内容类型 1.文字 2.图片  等等...--0.系统消息
                    msg.put("msgType",1001);
                    //将群的人数减一
                    R_PROPERTY.hset(groupId,"count", String.valueOf(count-tagIdList.size()));
                    break;
                case 2://踢人
                    Out.debug("----------------------踢人---------------------------");
                    //开始判断权限
                    if (!"1".equals(adminType)&&!"2".equals(adminType)){
                        return error(ErrorCodeList.JURISDICTION_INSUFFICIENT);//返回权限不足
                    }
                    String name="";

                    for (int i=0;i<tagIdList.size();i++){
                        //在群里删除该用户
                        Out.debug("-------------本群的Id"+groupId);
                        String userId=String.valueOf(tagIdList.get(i));
                        Out.debug("-------------------被踢的人"+userId);


                        name+=R_USER.hget(userId,NICKNAME)+"\n\n";

                        R_GROUP.hdel(groupId, userId);
                        //在用户-群的关系中判断这个用户中是否有该群
                        Out.info("---------"+R_USER_R_GROUP.exists(userId));


                        if (R_USER_R_GROUP.exists(userId)){
                            Out.info("-----------------当前用户保存了该群--需要解除------------------");
                            //将群-用户关系解除
                            R_USER_R_GROUP.lrem(userId,0,groupId);
                            /*if (R_USER_R_GROUP.lrem(userId,0,groupId)<1){
                                return error(ErrorCodeList.GROUP_USER__ERROR);
                            }*/
                        }
                    }

                    //TODO 加入管理员昵称
                    msg.put("msgContent",name+"被移除该群");
                    //内容类型 1.文字 2.图片  等等...--0.系统消息
                    msg.put("msgType",1002);
                    R_PROPERTY.hset(groupId,"count", String.valueOf(count-tagIdList.size()));
                    break;

                case 3://解散群
                    Out.debug("----------------------解散群---------------------------");
                    //权限判断
                    if (!"1".equals(adminType)){//权限不足
                        return error(ErrorCodeList.JURISDICTION_INSUFFICIENT);
                    }
                    //-------------------------开始将群-用户关系解除-------------------------

                    for (Object o:memberList){//开始解除每个成员里有多个群这里只解除当前群
                        R_USER_R_GROUP.lrem(String.valueOf(o),0, groupId);
                    }

                    //将本群的成员列表干掉
                    R_GROUP.del(groupId);
                    //将本群的详情信息干掉
                    R_PROPERTY.del(groupId);

                    msg.put("msgContent","本群已被解散");
                    //内容类型 1.文字 2.图片  等等...--0.系统消息
                    msg.put("msgType",1003);
                    break;
            }

            pushUpdate.setGroupId(groupId);//群聊id
            //循环群列表给每个接收者发送更新
            for (Object receiver: memberList){
                MsgService.pushAndSavedUnique((pushProto(String.valueOf(receiver),"push.groupUpdate",pushUpdate)),"push.groupUpdate-"+receiver);
            }

            msg.put("srcId","0");
            //获取目标用户id
            msg.put("tagId",groupId);
            //获取消息内容--case中定义了
            //内容类型 1.文字 2.图片  等等...--0.系统消息--case中定义了
            //获取消息类型1.单发  2.群发
            msg.put("tagType",2);
            //消息时间
            msg.put("time", DateUtil.getDateTime());
            //添加Redis的消息库中
            String msgId= IdService.newMsgId();
            R_MESSAGES.set(msgId,msg.toJSONString());

            pushsys.setUserId(groupId);
            pushsys.setMsgId(msgId);

            //AuroraPush.pushAurora(msgId);//极光推送
            //系统推送消息
            for (Object receiver: memberList){
                MsgService.pushAndSaved(pushProto(String.valueOf(receiver),"push.Msg",pushsys));
            }

            res.setMsg(ReturnUtils.ErrorProto(ErrorCodeList.SUCCESS));
            return responseProto(res);
        }catch (InvalidProtocolBufferException e){
            e.printStackTrace();
            return responseProto(res.setMsg(ReturnUtils.ErrorProto(ErrorCodeList.SERVER_ERROR)));
        }
    }
}
